var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

var eventTargetPolyfill = {};

var hasRequiredEventTargetPolyfill;

function requireEventTargetPolyfill () {
	if (hasRequiredEventTargetPolyfill) return eventTargetPolyfill;
	hasRequiredEventTargetPolyfill = 1;
	const root =
	  (typeof globalThis !== "undefined" && globalThis) ||
	  (typeof self !== "undefined" && self) ||
	  (typeof commonjsGlobal !== "undefined" && commonjsGlobal);

	function isConstructor(fn) {
	  try {
	    new fn();
	  } catch (error) {
	    return false;
	  }
	  return true;
	}

	if (typeof root.Event !== "function" || !isConstructor(root.Event)) {
	  root.Event = (function () {
	    function Event(type, options) {
	        this.bubbles = !!options && !!options.bubbles;
	        this.cancelable = !!options && !!options.cancelable;
	        this.composed = !!options && !!options.composed;
	      this.type = type;
	    }

	    return Event;
	  })();
	}

	if (typeof root.EventTarget === "undefined" || !isConstructor(root.Event)) {
	  root.EventTarget = (function () {
	    function EventTarget() {
	      this.__listeners = new Map();
	    }

	    EventTarget.prototype = Object.create(Object.prototype);

	    EventTarget.prototype.addEventListener = function (
	      type,
	      listener,
	      options
	    ) {
	      if (arguments.length < 2) {
	        throw new TypeError(
	          `TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.`
	        );
	      }
	      const __listeners = this.__listeners;
	      const actualType = type.toString();
	      if (!__listeners.has(actualType)) {
	        __listeners.set(actualType, new Map());
	      }
	      const listenersForType = __listeners.get(actualType);
	      if (!listenersForType.has(listener)) {
	        // Any given listener is only registered once
	        listenersForType.set(listener, options);
	      }
	    };

	    EventTarget.prototype.removeEventListener = function (
	      type,
	      listener,
	      _options
	    ) {
	      if (arguments.length < 2) {
	        throw new TypeError(
	          `TypeError: Failed to execute 'addEventListener' on 'EventTarget': 2 arguments required, but only ${arguments.length} present.`
	        );
	      }
	      const __listeners = this.__listeners;
	      const actualType = type.toString();
	      if (__listeners.has(actualType)) {
	        const listenersForType = __listeners.get(actualType);
	        if (listenersForType.has(listener)) {
	          listenersForType.delete(listener);
	        }
	      }
	    };

	    EventTarget.prototype.dispatchEvent = function (event) {
	      if (!(event instanceof Event)) {
	        throw new TypeError(
	          `Failed to execute 'dispatchEvent' on 'EventTarget': parameter 1 is not of type 'Event'.`
	        );
	      }
	      const type = event.type;
	      const __listeners = this.__listeners;
	      const listenersForType = __listeners.get(type);
	      if (listenersForType) {
	        for (const [listener, options] of listenersForType.entries()) {
	          try {
	            if (typeof listener === "function") {
	              // Listener functions must be executed with the EventTarget as the `this` context.
	              listener.call(this, event);
	            } else if (listener && typeof listener.handleEvent === "function") {
	              // Listener objects have their handleEvent method called, if they have one
	              listener.handleEvent(event);
	            }
	          } catch (err) {
	            // We need to report the error to the global error handling event,
	            // but we do not want to break the loop that is executing the events.
	            // Unfortunately, this is the best we can do, which isn't great, because the
	            // native EventTarget will actually do this synchronously before moving to the next
	            // event in the loop.
	            setTimeout(() => {
	              throw err;
	            });
	          }
	          if (options && options.once) {
	            // If this was registered with { once: true }, we need
	            // to remove it now.
	            listenersForType.delete(listener);
	          }
	        }
	      }
	      // Since there are no cancellable events on a base EventTarget,
	      // this should always return true.
	      return true;
	    };

	    return EventTarget;
	  })();
	}
	return eventTargetPolyfill;
}

requireEventTargetPolyfill();

var yetAnotherAbortcontrollerPolyfill = {};

var hasRequiredYetAnotherAbortcontrollerPolyfill;

function requireYetAnotherAbortcontrollerPolyfill () {
	if (hasRequiredYetAnotherAbortcontrollerPolyfill) return yetAnotherAbortcontrollerPolyfill;
	hasRequiredYetAnotherAbortcontrollerPolyfill = 1;
	const root =
	  (typeof globalThis !== "undefined" && globalThis) ||
	  (typeof self !== "undefined" && self) ||
	  (typeof commonjsGlobal !== "undefined" && commonjsGlobal);

	if (typeof root.AbortController === "undefined") {
	  const SECRET = {};

	  root.AbortSignal = (function () {
	    function AbortSignal(secret) {
	      if (secret !== SECRET) {
	        throw new TypeError("Illegal constructor.");
	      }
	      EventTarget.call(this);
	      this._aborted = false;
	    }

	    AbortSignal.prototype = Object.create(EventTarget.prototype);
	    AbortSignal.prototype.constructor = AbortSignal;

	    Object.defineProperty(AbortSignal.prototype, "onabort", {
	      get: function () {
	        return this._onabort;
	      },
	      set: function (callback) {
	        const existing = this._onabort;
	        if (existing) {
	          this.removeEventListener("abort", existing);
	        }
	        this._onabort = callback;
	        this.addEventListener("abort", callback);
	      },
	    });

	    Object.defineProperty(AbortSignal.prototype, "aborted", {
	      get: function () {
	        return this._aborted;
	      },
	    });

	    return AbortSignal;
	  })();

	  root.AbortController = (function () {
	    function AbortController() {
	      this._signal = new AbortSignal(SECRET);
	    }

	    AbortController.prototype = Object.create(Object.prototype);

	    Object.defineProperty(AbortController.prototype, "signal", {
	      get: function () {
	        return this._signal;
	      },
	    });

	    AbortController.prototype.abort = function () {
	      const signal = this.signal;
	      if (!signal.aborted) {
	        signal._aborted = true;
	        signal.dispatchEvent(new Event("abort"));
	      }
	    };

	    return AbortController;
	  })();
	}
	return yetAnotherAbortcontrollerPolyfill;
}

requireYetAnotherAbortcontrollerPolyfill();

// 声明一个 Map 用于存储每个请求的标识 和 取消函数
let pendingMap = new Map();
// 根据参数序列化，用于生成pendingMap的key
const getPendingUrl = (config) => [config.method, config.prefix, config.url].join("&");
class RequestAbort {
    /**
     * @description: 添加请求
     * @param {Object} config
     */
    addPending(config) {
        // 在请求开始前，对之前的请求做检查取消操作
        this.removePending(config);
        const url = getPendingUrl(config);
        const controller = new AbortController(); // 创建一个控制器
        const { signal } = controller; // 返回一个 AbortSignal 对象实例，它可以用来 with/abort 一个 DOM 请求
        config.signal = signal; // 这将信号和控制器与获取请求相关联然后允许我们通过调用 AbortController.abort() 中止请求
        if (!pendingMap.has(url)) {
            pendingMap.set(url, controller);
        }
    }
    /**
     * @description: 移除请求
     * @param {Object} config
     */
    removePending(config) {
        const url = getPendingUrl(config);
        // 如果在 pending 中存在当前请求标识，需要取消当前请求，并且移除
        if (pendingMap.has(url)) {
            const controller = pendingMap.get(url);
            controller && controller.abort(); // 中止一个尚未完成的请求
            pendingMap.delete(url);
        }
    }
    /**
     * @description: 清空所有pending
     */
    removeAllPending() {
        pendingMap.forEach(controller => {
            controller && controller();
        });
        pendingMap.clear();
    }
    /**
     * @description: 重置
     */
    reset() {
        pendingMap = new Map();
    }
}
var requestAbort = new RequestAbort();

export { requestAbort as default };
